/** @file
  The implementation of match policy entry function in IpSecConfig application.

  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "IpSecConfig.h"
#include "Indexer.h"
#include "Match.h"

/**
  Private function to validate a buffer that should be filled with zero.

  @param[in] Memory    The pointer to the buffer.
  @param[in] Size      The size of the buffer.

  @retval TRUE     The memory is filled with zero.
  @retval FALSE    The memory isn't filled with zero.
**/
BOOLEAN
IsMemoryZero (
  IN VOID     *Memory,
  IN UINTN    Size
  )
{
  UINTN    Index;

  for (Index = 0; Index < Size; Index++) {
    if (*((UINT8 *) Memory + Index) != 0) {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Find the matching SPD with Indexer.

  @param[in] Selector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
  @param[in] Data        The pointer to the EFI_IPSEC_SPD_DATA structure.
  @param[in] Indexer     The pointer to the SPD_ENTRY_INDEXER structure.

  @retval TRUE     The matched SPD is found.
  @retval FALSE    The matched SPD is not found.
**/
BOOLEAN
MatchSpdEntry (
  IN EFI_IPSEC_SPD_SELECTOR    *Selector,
  IN EFI_IPSEC_SPD_DATA        *Data,
  IN SPD_ENTRY_INDEXER         *Indexer
  )
{
  BOOLEAN    Match;

  Match = FALSE;
  if (!IsMemoryZero (Indexer->Name, MAX_PEERID_LEN)) {
    if ((Data->Name != NULL) && (AsciiStrCmp ((CHAR8 *) Indexer->Name, (CHAR8 *) Data->Name) == 0)) {
      Match = TRUE;
    }
  } else {
    if (Indexer->Index == 0) {
      Match = TRUE;
    }

    Indexer->Index--;
  }

  return Match;
}

/**
  Find the matching SAD with Indexer.

  @param[in] SaId       The pointer to the EFI_IPSEC_SA_ID structure.
  @param[in] Data       The pointer to the EFI_IPSEC_SA_DATA2 structure.
  @param[in] Indexer    The pointer to the SPD_ENTRY_INDEXER structure.

  @retval TRUE     The matched SAD is found.
  @retval FALSE    The matched SAD is not found.
**/
BOOLEAN
MatchSadEntry (
  IN EFI_IPSEC_SA_ID      *SaId,
  IN EFI_IPSEC_SA_DATA2   *Data,
  IN SAD_ENTRY_INDEXER    *Indexer
  )
{
  BOOLEAN    Match;

  Match = FALSE;
  if (!IsMemoryZero (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID))) {
    Match = (BOOLEAN) (CompareMem (&Indexer->SaId, SaId, sizeof (EFI_IPSEC_SA_ID)) == 0);
  } else {
    if (Indexer->Index == 0) {
      Match = TRUE;
    }
    Indexer->Index--;
  }

  return Match;
}

/**
  Find the matching PAD with Indexer.

  @param[in] PadId      The pointer to the EFI_IPSEC_PAD_ID structure.
  @param[in] Data       The pointer to the EFI_IPSEC_PAD_DATA structure.
  @param[in] Indexer    The pointer to the SPD_ENTRY_INDEXER structure.

  @retval TRUE     The matched PAD is found.
  @retval FALSE    The matched PAD is not found.
**/
BOOLEAN
MatchPadEntry (
  IN EFI_IPSEC_PAD_ID      *PadId,
  IN EFI_IPSEC_PAD_DATA    *Data,
  IN PAD_ENTRY_INDEXER     *Indexer
  )
{
  BOOLEAN                       Match;

  Match = FALSE;
  if (!IsMemoryZero (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID))) {
    Match = (BOOLEAN) ((Indexer->PadId.PeerIdValid == PadId->PeerIdValid) &&
                       ((PadId->PeerIdValid &&
                         (StrCmp (
                            (CONST CHAR16 *) Indexer->PadId.Id.PeerId,
                            (CONST CHAR16 *) PadId->Id.PeerId
                            ) == 0)) ||
                        ((!PadId->PeerIdValid) &&
                         (Indexer->PadId.Id.IpAddress.PrefixLength == PadId->Id.IpAddress.PrefixLength) &&
                         (CompareMem (
                            &Indexer->PadId.Id.IpAddress.Address,
                            &PadId->Id.IpAddress.Address,
                            sizeof (EFI_IP_ADDRESS)
                            ) == 0))));
  } else {
    if (Indexer->Index == 0) {
      Match = TRUE;
    }

    Indexer->Index--;
  }

  return Match;
}

MATCH_POLICY_ENTRY mMatchPolicyEntry[] = {
  (MATCH_POLICY_ENTRY) MatchSpdEntry,
  (MATCH_POLICY_ENTRY) MatchSadEntry,
  (MATCH_POLICY_ENTRY) MatchPadEntry
};

